package com.fivefu.core.data.services.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.fivefu.base.common.utils.str.StrUtils;
import com.fivefu.core.data.constant.PlatformEnum;
import com.fivefu.core.data.entity.DbFfskyeyeDevice;
import com.fivefu.core.data.entity.DbFfskyeyePlatform;
import com.fivefu.core.data.entity.DbFfskyeyeRegion;
import com.fivefu.core.data.mapper.DbFfskyeyeDeviceMapper;
import com.fivefu.core.data.services.DbFfskyeyeDeviceService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fivefu.core.data.services.DbFfskyeyePlatformService;
import com.fivefu.core.data.services.DbFfskyeyeRegionDeviceService;
import com.fivefu.core.data.services.DbFfskyeyeRegionService;
import com.fivefu.core.hik.entity.DbHikDevice;
import com.fivefu.core.hik.entity.DbHikRegionsDevice;
import com.fivefu.core.hik.services.DbHikDeviceService;
import com.fivefu.core.hik.services.DbHikRegionsDeviceService;
import com.fivefu.core.hillstone.entity.DbHillstoneDevice;
import com.fivefu.core.hillstone.services.DbHillstoneDeviceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 设备 服务实现类
 * </p>
 *
 * @author 
 * @since 2022-09-01 19:22:07
 */
@Service
public class DbFfskyeyeDeviceServiceImpl extends ServiceImpl<DbFfskyeyeDeviceMapper, DbFfskyeyeDevice> implements DbFfskyeyeDeviceService {

    @Autowired
    private DbFfskyeyeRegionService dbFfskyeyeRegionService;
    @Autowired
    private DbFfskyeyeRegionDeviceService dbFfskyeyeRegionDeviceService;
    @Autowired
    private DbHillstoneDeviceService dbHillstoneDeviceService;
    @Autowired
    private DbHikDeviceService dbHikDeviceService;
    @Autowired
    private DbHikRegionsDeviceService dbHikRegionsDeviceService;
    @Autowired
    private DbFfskyeyePlatformService dbFfskyeyePlatformService;


    /**
     * 通过设备唯一标识查询相关数据信息
     * @param deviceCode   设备唯一标识
     * @return
     */
    private DbFfskyeyeDevice queryByDeviceCode(String deviceCode) {
        QueryWrapper<DbFfskyeyeDevice> wrapper = new QueryWrapper<>();
        wrapper.eq("is_delete",0);
        wrapper.eq("device_code",deviceCode);
        DbFfskyeyeDevice dbFfskyeyeDevice = baseMapper.selectOne(wrapper);
        return dbFfskyeyeDevice;

    }

    private void insertCollectDevice(List<DbFfskyeyeDevice> formatList,String platFormCode) {
        LocalDateTime time = LocalDateTime.now();
        for (DbFfskyeyeDevice dbFfskyeyeDevice : formatList) {
            dbFfskyeyeDevice.setCreatedBy("sys");
            dbFfskyeyeDevice.setCreatedTime(time);
            dbFfskyeyeDevice.setUpdatedBy("sys");
            dbFfskyeyeDevice.setUpdatedTime(time);
            dbFfskyeyeDevice.setIsDelete(0);
            dbFfskyeyeDevice.setPlatformCode(platFormCode);
            //使用uuid生成设备唯一标识
            String s = UUID.randomUUID().toString();
            dbFfskyeyeDevice.setDeviceCode(s);
            DbFfskyeyeRegion dbFfskyeyeRegion = dbFfskyeyeRegionService.queryRegion(dbFfskyeyeDevice.getPlatformRegionCode(),platFormCode);
            dbFfskyeyeDevice.setRegionId(dbFfskyeyeRegion.getId());
        }
        saveBatch(formatList);
    }

    /**
     * 查询本地平台所有设备数据信息集
     * @param platFormCode   平台标识
     * @return
     */
    @Override
    public List<DbFfskyeyeDevice> queryAllPlatDevice(String platFormCode) {
        QueryWrapper<DbFfskyeyeDevice> wrapper = new QueryWrapper<>();
        wrapper.eq("is_delete",0);
        wrapper.eq("platform_code",platFormCode);
        List<DbFfskyeyeDevice> deviceList = baseMapper.selectList(wrapper);
        return deviceList;
    }

    /**
     * 删除编码信息
     * @param deviceList2
     */
    private void deleteCollectDeviceById(List<DbFfskyeyeDevice> deviceList2) {
        for (DbFfskyeyeDevice dbFfskyeyeDevice : deviceList2) {
            dbFfskyeyeDevice.setIsDelete(1);
            dbFfskyeyeDevice.setUpdatedBy("sys");
            dbFfskyeyeDevice.setUpdatedTime(LocalDateTime.now());
            //删除编码信息
            baseMapper.updateById(dbFfskyeyeDevice);
        }

    }

    /**
     * 转换海康编码设备表返回的数据信息
     * @param respList
     * @return
     */
    private List<DbFfskyeyeDevice> formatHik(List<DbHikDevice> respList, String platformCode) {
        List<DbFfskyeyeDevice> resultList = new ArrayList<>();
        if (null == respList || respList.size() <= 0) {
            return resultList;
        }
        respList.forEach(resp -> {
            DbFfskyeyeDevice device = new DbFfskyeyeDevice();
            device.setPlatformDeviceCode(resp.getIndexCode());
            if (StrUtils.isNotNull(resp.getIp())) {
                device.setDeviceIp(resp.getIp());
            }
            if (null != resp.getPort()) {
                device.setDevicePort(Integer.valueOf(resp.getPort()));
            }
            //转存数据字典中的协议类型
            if (StrUtils.isNotNull(resp.getTreatyType())) {
                device.setProtocolType(resp.getTreatyType());
            }
            //转存数据字典中的设备类型
            if (StrUtils.isNotNull(resp.getResourceType())) {
                device.setDeviceType(resp.getResourceType());
            }
            if (StrUtils.isNotNull(resp.getDeviceKeyVersion())) {
                device.setDeviceModel(resp.getDeviceKeyVersion());
            }
            if (StrUtils.isNotNull(resp.getName())) {
                device.setDeviceName(resp.getName());
            }
            if (StrUtils.isNotNull(resp.getDevSerialNum())) {
                device.setDeviceSerialNum(resp.getDevSerialNum());
            }
            //转存数据字典中的厂商类型
            if (StrUtils.isNotNull(resp.getManufacturer())) {
                device.setDeviceManufacturer(resp.getManufacturer());
            }
            if (StrUtils.isNotNull(resp.getIndexCode())) {
                DbHikRegionsDevice regionsDevice = dbHikRegionsDeviceService.queryRegionByDeviceCode(resp.getIndexCode());
                if (null != regionsDevice) {
                    if (StrUtils.isNotNull(regionsDevice.getRegionIndexCode())) {
                        device.setPlatformRegionCode(regionsDevice.getRegionIndexCode());
                    }
                }
            }

            DbFfskyeyeRegion dbFfskyeyeRegion = dbFfskyeyeRegionService.queryRegion(device.getPlatformRegionCode(),platformCode);
            if (null != dbFfskyeyeRegion) {
                device.setRegionId(dbFfskyeyeRegion.getId());
            }
            device.setPlatformCode(platformCode);
            resultList.add(device);
        });
        return resultList;
    }

    /**
     * 根据平台设备唯一编码及平台标记查询
     * @param platFormDeviceCode    平台设备唯一编码
     * @param platFormCode          平台标记
     * @return
     */
    @Override
    public DbFfskyeyeDevice queryDevice(String platFormDeviceCode,String platFormCode) {
        QueryWrapper<DbFfskyeyeDevice> wrapper = new QueryWrapper<>();
        wrapper.eq("is_delete",0);
        wrapper.eq("platform_device_code",platFormDeviceCode);
        wrapper.eq("platform_code",platFormCode);
        DbFfskyeyeDevice device = baseMapper.selectOne(wrapper);
        return device;
    }

    /**
     * 更新本地设备信息
     * @param addedList
     * @param platFormCode   平台标记
     */
    private void updateFormatDevice(List<DbFfskyeyeDevice> addedList, String platFormCode) {
        if (null == addedList || addedList.size() <= 0) {
            return;
        }
        LocalDateTime time = LocalDateTime.now();
        for (DbFfskyeyeDevice device : addedList) {
            //根据平台设备唯一编码及平台标记查询
            DbFfskyeyeDevice oldDevice = queryDevice(device.getPlatformDeviceCode(),platFormCode);
            device.setId(oldDevice.getId());
            device.setUpdatedTime(time);
            device.setUpdatedBy("sys");
            device.setPlatformCode(platFormCode);
            DbFfskyeyeRegion dbFfskyeyeRegion = dbFfskyeyeRegionService.queryRegion(device.getPlatformRegionCode(),platFormCode);
            device.setRegionId(dbFfskyeyeRegion.getId());
            baseMapper.updateById(device);
        }
    }

    private List<DbFfskyeyeDevice> formatHill(List<DbHillstoneDevice> hillList, String platformCode) {
        List<DbFfskyeyeDevice> resultList = new ArrayList<>();
        if (null == hillList || hillList.size() <= 0) {
            return resultList;
        }
        hillList.forEach(resp -> {
            DbFfskyeyeDevice device = new DbFfskyeyeDevice();
            device.setPlatformDeviceCode(resp.getDeviceCode());//平台设备唯一编码
            if (StrUtils.isNotNull(resp.getDeviceIp())) {
                device.setDeviceIp(resp.getDeviceIp());//IP地址
            }
            if (null != resp.getOnline()) {
                device.setOnlineStatus(resp.getOnline());//在线状态
            }
            if (StrUtils.isNotNull(resp.getOrganizationCode())) {
                device.setPlatformRegionCode(resp.getOrganizationCode());//平台域唯一标识
                DbFfskyeyeRegion dbFfskyeyeRegion = dbFfskyeyeRegionService.queryRegion(device.getPlatformRegionCode(),platformCode);
                device.setRegionId(dbFfskyeyeRegion.getId());
            }
            if (StrUtils.isNotNull(resp.getDeviceManufacturer())) {
                device.setDeviceManufacturer(resp.getDeviceManufacturer());//厂商
            }
            if (StrUtils.isNotNull(resp.getSubType())) {
                device.setDeviceType(resp.getSubType());//设备类型
            }
            if (null != resp.getDevicePort()) {
                device.setDevicePort(resp.getDevicePort());//端口号
            }
            if (StrUtils.isNotNull(resp.getProtocolType())) {
                device.setProtocolType(resp.getProtocolType());//协议类型
            }
            if (StrUtils.isNotNull(resp.getDeviceModel())) {
                device.setDeviceModel(resp.getDeviceModel());//设备型号
            }
            if (StrUtils.isNotNull(resp.getDeviceName())) {
                device.setDeviceName(resp.getDeviceName());//设备名称
            }
            if (StrUtils.isNotNull(resp.getDeviceSn())) {
                device.setDeviceSerialNum(resp.getDeviceSn());//设备序列号
            }
            if (StrUtils.isNotNull(resp.getMemo())) {
                device.setDeviceRemark(resp.getMemo());//设备备注
            }
            if (null != resp.getMediaPort()) {
                device.setMediaPort(resp.getMediaPort());//媒体端口
            }

            device.setPlatformCode(platformCode);
            resultList.add(device);
        });
        return resultList;
    }

    /**
     * 根据平台设备唯一标识集查询对应的汇总设备集
     * @param codeList
     * @return
     */
    private List<DbFfskyeyeDevice> getDeviceCodes(List<String> codeList) {
        QueryWrapper<DbFfskyeyeDevice> wrapper = new QueryWrapper<>();
        wrapper.eq("is_delete",0);
        wrapper.in("platform_device_code",codeList);
        List<DbFfskyeyeDevice> deviceList = baseMapper.selectList(wrapper);
        return deviceList;
    }

    /**
     * 删除多余的设备信息数据
     * @param codeList
     */
    private void deleteCollectDevice(List<String> codeList,String platFormCode,String userId) {
        QueryWrapper<DbFfskyeyeDevice> wrapper = new QueryWrapper<>();
        wrapper.eq("is_delete",0);
        if (!codeList.isEmpty()) {
            wrapper.notIn("platform_device_code",codeList);
        }
        wrapper.eq("platform_code",platFormCode);

        DbFfskyeyeDevice device = new DbFfskyeyeDevice();
        device.setIsDelete(1);
        device.setUpdatedTime(LocalDateTime.now());
        device.setUpdatedBy(userId);
        baseMapper.update(device,wrapper);
    }

    /**
     * 编辑汇总设备信息
     * @param device
     * @param platFormCode
     */
    private void editorDbFfskyeyeDevice(DbFfskyeyeDevice device,String platFormCode,String userId) {
        LocalDateTime time = LocalDateTime.now();
        DbFfskyeyeDevice oldDevice = queryDevice(device.getPlatformDeviceCode(), platFormCode);
        device.setUpdatedTime(time);
        device.setUpdatedBy(userId);

        if (null != oldDevice) {
            device.setId(oldDevice.getId());
            baseMapper.updateById(device);
        } else {
            device.setCreatedTime(time);
            device.setCreatedBy(userId);
            device.setIsDelete(0);
            String s = UUID.randomUUID().toString();
            device.setDeviceCode(s);
            baseMapper.insert(device);
        }
        if (null != device.getId() && null != device.getRegionId()) {
            dbFfskyeyeRegionDeviceService.editorRegionDevice(device.getId(),device.getRegionId(),userId);
        }
    }

    /**
     * 查询设备列表
     * @param deleteFlag 删除标识
     * @param platFormCode 平台标识
     * @return
     */
    @Override
    public List<DbFfskyeyeDevice> queryDevicelList(Integer deleteFlag, String platFormCode){
        QueryWrapper<DbFfskyeyeDevice> wrapper = new QueryWrapper<DbFfskyeyeDevice>();
        if (deleteFlag != null){
            wrapper.eq("is_delete",deleteFlag);
        }
        if (StrUtils.isNotNull(platFormCode)) {
            wrapper.eq("platform_code", platFormCode);
        }
        List<DbFfskyeyeDevice> deviceList = baseMapper.selectList(wrapper);
        return deviceList;
    }

    /**
     * 通过编号查询设备信息
     * @param deviceID 设备编号
     * @return
     */
    @Override
    public DbFfskyeyeDevice queryDeviceByID(Long deviceID){
        DbFfskyeyeDevice device = baseMapper.selectById(deviceID);
        return device;
    }

    /**
     * 设备信息入库
     * @param platformName   设备平台：海康,大华
     * @param userId 用户编号
     */
    @Override
    public void deviceCollect(String platformName,String userId) {
        DbFfskyeyePlatform platform = dbFfskyeyePlatformService.queryPlatformByName(platformName);
        String platformCode = platformName;
        if (platform != null) {
            platformCode = platform.getPlatformCode();
        }
        List<DbFfskyeyeDevice> deviceList = new ArrayList<>();
        if (PlatformEnum.HIKVERSION.getPlatformCode().equals(platformCode)) {
            //查询海康编码设备表数据
            List<DbHikDevice> respList = dbHikDeviceService.queryAllDevice();
            if (null == respList || respList.size() <= 0) {
                return;
            }
            //转换海康编码设备表返回的数据信息
            deviceList = formatHik(respList, platformCode);
        } else {
            //查询大华设备表数据
            List<DbHillstoneDevice> hillList = dbHillstoneDeviceService.queryAllDevice();
            if (null == hillList || hillList.size() <= 0) {
                return;
            }
            //转换大华设备表返回的数据信息
            deviceList = formatHill(hillList, platformCode);
        }
        List<String> codeHillList = deviceList.stream().map(k -> k.getPlatformDeviceCode()).collect(Collectors.toList());
        //编辑设备信息
        for (DbFfskyeyeDevice device : deviceList) {
            editorDbFfskyeyeDevice(device,platformCode,userId);
        }
        //删除多余的大华设备信息数据
        deleteCollectDevice(codeHillList,platformCode,userId);

        //删除其他域下关联的设备信息
        List<DbFfskyeyeRegion> allList = dbFfskyeyeRegionService.queryAll();
        dbFfskyeyeRegionDeviceService.deleteRedundantRegionDevice(allList,userId);
    }

    /**
     * 编辑设备
     * @param device 设备信息
     * @param userid 操作用户编号
     */
    @Override
    public Long editDeviceById(DbFfskyeyeDevice device, String userid){
        LocalDateTime time = LocalDateTime.now();
        device.setUpdatedBy(userid);
        device.setUpdatedTime(time);
        if (device.getId() != null){
            baseMapper.updateById(device);
        }else{
            device.setDeviceCode(UUID.randomUUID().toString());

            device.setCreatedBy(userid);
            device.setCreatedTime(time);
            device.setIsDelete(0);
            baseMapper.insert(device);
        }
        return device.getId();
    }

    /**
     * 删除设备
     * @param deviceId 设备编号
     * @param userid 操作用户编号
     */
    @Override
    public void deleteDeviceById(Long deviceId, String userid){
        UpdateWrapper<DbFfskyeyeDevice> wrapper = new UpdateWrapper<>();
        wrapper.eq("is_delete",0);
        wrapper.eq("id", deviceId);

        wrapper.set("is_delete", 1);
        wrapper.set("updated_by", userid);
        wrapper.set("updated_time", LocalDateTime.now());
        baseMapper.update(null, wrapper);
    }
}
